<template>
  <view class="container">
    <view class="header">
      <image class="logo" src="/static/logo.png" mode="aspectFit"></image>
      <view class="title">栖岛授权登录</view>
      <view class="subtitle">OAuth2.0 Demo</view>
    </view>
    
    <view v-if="userInfo && userInfo.user" class="user-profile">
      <image class="avatar" :src="userInfo.user.avatar || '/static/default-avatar.png'" mode="aspectFill"></image>
      <view class="user-info">
        <view class="username">{{ userInfo.user.screenName || '未知用户' }}</view>
        <view class="uid">UID: {{ userInfo.user.uid }}</view>
      </view>
      <view class="auth-status">
        <view class="auth-tag">已授权</view>
      </view>
    </view>
    
    <view class="card-container" v-if="!userInfo">
      <view class="card auth-card">
        <view class="card-title">
          <text class="icon">🔐</text>
          <text>授权登录</text>
        </view>
        <view class="card-content">
          <view class="description">点击下方按钮，使用栖岛账号登录</view>
          <button @click="authorizeWithQidao" type="primary" class="auth-btn">
            <text class="btn-icon">🚀</text> 启动栖岛授权
          </button>
        </view>
      </view>
      
      <view v-if="schemeData" class="card data-card">
        <view class="card-title">
          <text class="icon">📝</text>
          <text>授权信息</text>
        </view>
        <view class="card-content">
          <view class="data-item">
            <text class="label">授权码:</text>
            <text class="value code-value">{{ schemeData.code }}</text>
          </view>
          <view class="data-item">
            <text class="label">状态码:</text>
            <text class="value">{{ schemeData.state }}</text>
          </view>
          <view class="data-item" v-if="stateVerified !== null">
            <text class="label">验证状态:</text>
            <text class="value" :class="stateVerified ? 'status-success' : 'status-error'">
              {{ stateVerified ? '验证通过 ✓' : '验证失败 ✗' }}
            </text>
          </view>
          
          <button @click="getUserInfo" type="primary" class="get-info-btn">
            <text class="btn-icon">👤</text> 获取用户信息
          </button>
        </view>
      </view>
    </view>
    
    <view v-if="userInfo" class="card-container">
      <view class="card user-card">
        <view class="card-title">
          <text class="icon">👤</text>
          <text>用户信息</text>
        </view>
        <view class="card-content">
          <view class="profile-section">
            <view class="profile-item">
              <text class="profile-label">用户名</text>
              <text class="profile-value">{{ userInfo.user && userInfo.user.screenName || '未知' }}</text>
            </view>
            <view class="profile-item">
              <text class="profile-label">用户ID</text>
              <text class="profile-value">{{ userInfo.user && userInfo.user.uid || '未知' }}</text>
            </view>
          </view>
        </view>
      </view>
      
      <view class="card token-card">
        <view class="card-title">
          <text class="icon">🔑</text>
          <text>令牌信息</text>
        </view>
        <view class="card-content">
          <view class="token-section">
            <view class="token-item">
              <text class="token-label">Access Token</text>
              <text class="token-value ellipsis">{{ userInfo.access_token }}</text>
              <button class="copy-btn" @click="copyText(userInfo.access_token)">复制</button>
            </view>
            <view class="token-item">
              <text class="token-label">Token Type</text>
              <text class="token-value">{{ userInfo.token_type }}</text>
            </view>
            <view class="token-item">
              <text class="token-label">过期时间</text>
              <text class="token-value">{{ userInfo.expires_in }}秒</text>
            </view>
            <view class="token-item">
              <text class="token-label">Refresh Token</text>
              <text class="token-value ellipsis">{{ userInfo.refresh_token }}</text>
              <button class="copy-btn" @click="copyText(userInfo.refresh_token)">复制</button>
            </view>
            <view class="token-item">
              <text class="token-label">Scope</text>
              <text class="token-value">{{ userInfo.scope || '无' }}</text>
            </view>
          </view>
        </view>
      </view>
      
      <button @click="logout" type="default" class="logout-btn">
        退出登录
      </button>
    </view>
    
    <view v-if="!schemeData && !userInfo" class="empty-state">
      <image class="empty-icon" src="/static/logo.png" mode="aspectFit"></image>
      <view class="empty-text">请点击上方按钮进行栖岛授权</view>
    </view>
    
    <view class="footer">
      <view class="action-buttons" v-if="!userInfo">
        <button @click="showManualInput" type="default" class="action-btn">
          手动输入回调
        </button>
        <button @click="checkLaunchOptions" type="default" class="action-btn">
          检查启动参数
        </button>
      </view>
      <view class="copyright">
        © 2023 栖岛 OAuth2.0 Demo
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      schemeData: null,
      currentState: '',
      stateVerified: null,
      lastAuthUrl: '',
      userInfo: null,
      loading: false
    }
  },
  onLoad() {
    // 生成随机状态码
    if (getApp().generateRandomState) {
      this.currentState = getApp().generateRandomState();
    } else {
      this.generateRandomState();
    }
    
    // 从全局获取
    if (getApp().globalData && getApp().globalData.schemeData) {
      this.schemeData = getApp().globalData.schemeData;
      this.verifyState();
    }
    
    // 从本地存储获取
    const storageData = uni.getStorageSync('scheme_data');
    if (storageData) {
      this.schemeData = storageData;
      this.verifyState();
    }
    
    // 检查是否有保存的用户信息
    const userInfo = uni.getStorageSync('user_info');
    if (userInfo) {
      this.userInfo = userInfo;
    }
    
    // 监听全局事件
    uni.$on('scheme-data-received', this.handleSchemeData);
    
    // 检查启动参数
    this.checkLaunchOptions();
    
    console.log('页面加载完成，开始监听scheme回调');
  },
  onShow() {
    // 在页面显示时也检查一次启动参数，以确保捕获回调
    console.log('页面显示，检查启动参数');
    this.checkLaunchOptions();
    
    // 检查是否有来自URL Scheme的数据
    // #ifdef APP-PLUS
    plus.runtime.arguments && this.parseSchemeArgs(plus.runtime.arguments);
    // #endif
  },
  onUnload() {
    uni.$off('scheme-data-received', this.handleSchemeData);
  },
  methods: {
    // 复制文本
    copyText(text) {
      uni.setClipboardData({
        data: text,
        success: () => {
          uni.showToast({
            title: '复制成功',
            icon: 'success'
          });
        }
      });
    },
    
    // 退出登录
    logout() {
      uni.showModal({
        title: '退出登录',
        content: '确定要退出当前登录吗？',
        success: (res) => {
          if (res.confirm) {
            // 清除用户信息
            this.userInfo = null;
            uni.removeStorageSync('user_info');
            
            uni.showToast({
              title: '已退出登录',
              icon: 'success'
            });
          }
        }
      });
    },
    
    // 获取用户信息
    getUserInfo() {
      if (!this.schemeData || !this.schemeData.code) {
        uni.showToast({
          title: '未获取到授权码',
          icon: 'none'
        });
        return;
      }
      
      if (this.loading) return;
      this.loading = true;
      
      uni.showLoading({
        title: '获取用户信息中...'
      });
      
      // 构建请求URL,这个Demo的URL使用的是后端/Qidoa_OAuth2.0_Demo/Qidao_Server_ApiDemo/index.php文件，自己部署改为自己的
      const url = `https://server.tvcloud.top/test/index.php?code=${this.schemeData.code}&state=${this.schemeData.state || this.currentState}`;
      
      console.log('请求用户信息:', url);
      
      // 发起请求
      uni.request({
        url: url,
        method: 'GET',
        success: (res) => {
          console.log('获取用户信息结果:', res);
          
          if (res.statusCode === 200) {
            // 处理响应数据
            if (res.data.success) {
              this.userInfo = res.data;
              uni.showToast({
                title: '获取用户信息成功',
                icon: 'success'
              });
              
              // 保存用户信息到本地存储
              uni.setStorageSync('user_info', this.userInfo);
            } else {
              uni.showToast({
                title: res.data.error_description || '获取用户信息失败',
                icon: 'none'
              });
            }
          } else {
            uni.showToast({
              title: '请求失败: ' + res.statusCode,
              icon: 'none'
            });
          }
        },
        fail: (err) => {
          console.error('请求失败:', err);
          uni.showToast({
            title: '网络请求失败',
            icon: 'none'
          });
        },
        complete: () => {
          this.loading = false;
          uni.hideLoading();
        }
      });
    },
    
    // 显示手动输入回调参数的对话框
    showManualInput() {
      uni.showModal({
        title: '手动输入回调参数',
        content: '请输入栖岛返回的回调URL',
        editable: true,
        placeholderText: 'test://callback?code=xxx&state=yyy',
        success: (res) => {
          if (res.confirm && res.content) {
            console.log('手动输入的回调URL:', res.content);
            this.parseSchemeArgs(res.content);
          }
        }
      });
    },
    
    // 解析从URL Scheme传递过来的参数
    parseSchemeArgs(args) {
      console.log('收到scheme参数:', args);
      
      try {
        // 尝试解析URL格式的参数
        if (args.indexOf('://') > -1) {
          const urlParts = args.split('?');
          if (urlParts.length > 1) {
            const params = {};
            const paramPairs = urlParts[1].split('&');
            
            for (const pair of paramPairs) {
              const [key, value] = pair.split('=');
              if (key && value) {
                params[key] = decodeURIComponent(value);
              }
            }
            
            if (params.code) {
              this.handleSchemeData(params);
            }
          }
        }
      } catch (e) {
        console.error('解析scheme参数失败:', e);
      }
    },
    
    // 使用七道进行授权
    authorizeWithQidao() {
      // 生成随机状态码
      if (getApp().generateRandomState) {
        this.currentState = getApp().generateRandomState();
      } else {
        this.generateRandomState();
      }
      
      // 保存当前状态码到本地，用于后续验证
      uni.setStorageSync('current_state', this.currentState);
      
      // 构建授权URL (确保编码正确)
      // 注意: redirect_uri 必须包含完整的回调地址，包括协议和路径
      // 直接使用预编码的值
      const authUrl = `qidao://authorize?client_id=test_client&redirect_uri=test2121212%3A%2F%2Fcallback&scope=screen_name avatar&state=${this.currentState}&response_type=code`;
      
      // 保存授权URL用于显示
      this.lastAuthUrl = authUrl;
      
      console.log('授权URL:', authUrl);
      
      // 打开外部应用
      // #ifdef APP-PLUS
      plus.runtime.openURL(authUrl, (err) => {
        if (err) {
          console.error('打开URL失败:', err);
          uni.showToast({
            title: '打开栖岛应用失败',
            icon: 'none'
          });
        } else {
          console.log('成功打开栖岛应用');
          // 成功打开后显示提示
          uni.showToast({
            title: '已跳转到栖岛授权',
            icon: 'none',
            duration: 2000
          });
        }
      });
      // #endif
      
      // #ifndef APP-PLUS
      uni.showToast({
        title: '当前平台不支持打开外部应用',
        icon: 'none'
      });
      // #endif
    },
    
    // 生成随机状态码
    generateRandomState() {
      const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      let state = '';
      for (let i = 0; i < 16; i++) {
        state += chars.charAt(Math.floor(Math.random() * chars.length));
      }
      this.currentState = state;
      return state;
    },
    
    // 验证state是否匹配
    verifyState() {
      if (!this.schemeData || !this.schemeData.state) return;
      
      // 从存储中获取之前保存的state
      const savedState = uni.getStorageSync('current_state');
      
      if (savedState && this.schemeData.state) {
        this.stateVerified = savedState === this.schemeData.state;
      }
    },
    
    handleSchemeData(data) {
      console.log('收到Scheme数据:', data);
      this.schemeData = data;
      
      // 验证state
      this.verifyState();
      
      // 清除之前的用户信息
      this.userInfo = null;
      uni.removeStorageSync('user_info');
      
      uni.showToast({
        title: '收到授权数据',
        icon: 'success'
      });
    },
    
    checkLaunchOptions() {
      const launchOptions = uni.getLaunchOptionsSync();
      console.log('启动参数:', launchOptions);
      
      if (launchOptions.query && launchOptions.query.code) {
        this.handleSchemeData(launchOptions.query);
      } else {
        // 尝试从plus.runtime.arguments获取参数
        // #ifdef APP-PLUS
        if (plus && plus.runtime && plus.runtime.arguments) {
          console.log('从plus.runtime.arguments获取参数:', plus.runtime.arguments);
          this.parseSchemeArgs(plus.runtime.arguments);
        } else {
          console.log('未找到启动参数');
        }
        // #endif
        
        // #ifndef APP-PLUS
        console.log('未找到启动参数');
        // #endif
      }
    }
  }
}
</script>

<style>
page {
  background-color: #f8f8f8;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
    Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.container {
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
}

.header {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 30px;
  width: 100%;
}

.logo {
  width: 80px;
  height: 80px;
  margin-bottom: 10px;
  border-radius: 20px;
}

.title {
  font-size: 22px;
  font-weight: bold;
  color: #333;
  margin-bottom: 5px;
}

.subtitle {
  font-size: 14px;
  color: #666;
}

.user-profile {
  display: flex;
  align-items: center;
  width: 100%;
  background-color: #fff;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.avatar {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  margin-right: 15px;
  border: 2px solid #f0f0f0;
}

.user-info {
  flex: 1;
}

.username {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  margin-bottom: 5px;
}

.uid {
  font-size: 12px;
  color: #888;
}

.auth-status {
  margin-left: auto;
}

.auth-tag {
  background-color: #4CAF50;
  color: white;
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: bold;
}

.card-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.card {
  background-color: #fff;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  width: 100%;
}

.card-title {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.icon {
  margin-right: 8px;
  font-size: 18px;
}

.card-content {
  width: 100%;
}

.description {
  color: #666;
  margin-bottom: 15px;
  font-size: 14px;
}

.auth-btn {
  width: 100%;
  height: 45px;
  border-radius: 8px;
  font-size: 16px;
  background-color: #2d8cf0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-icon {
  margin-right: 8px;
}

.data-item {
  display: flex;
  margin-bottom: 12px;
  align-items: flex-start;
}

.label {
  font-weight: bold;
  color: #666;
  min-width: 80px;
  font-size: 14px;
}

.value {
  flex: 1;
  word-break: break-all;
  font-size: 14px;
  color: #333;
}

.code-value {
  font-family: monospace;
  background-color: #f5f5f5;
  padding: 3px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.status-success {
  color: #4CAF50;
  font-weight: bold;
}

.status-error {
  color: #F44336;
  font-weight: bold;
}

.get-info-btn {
  width: 100%;
  height: 45px;
  border-radius: 8px;
  margin-top: 15px;
  background-color: #2d8cf0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.profile-section, .token-section {
  width: 100%;
}

.profile-item, .token-item {
  margin-bottom: 15px;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 10px;
}

.profile-label, .token-label {
  font-size: 12px;
  color: #888;
  margin-bottom: 5px;
  display: block;
}

.profile-value, .token-value {
  font-size: 14px;
  color: #333;
  word-break: break-all;
}

.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
  white-space: nowrap;
  max-width: calc(100% - 60px);
}

.copy-btn {
  position: absolute;
  right: 25px;
  padding: 2px 8px;
  font-size: 12px;
  background-color: #f0f0f0;
  border: none;
  color: #666;
  border-radius: 4px;
  margin-top: -20px;
}

.token-item {
  position: relative;
}

.logout-btn {
  width: 100%;
  height: 45px;
  border-radius: 8px;
  font-size: 16px;
  margin-top: 10px;
  color: #666;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 40px 0;
}

.empty-icon {
  width: 100px;
  height: 100px;
  opacity: 0.3;
  margin-bottom: 20px;
}

.empty-text {
  color: #999;
  font-size: 14px;
}

.footer {
  margin-top: auto;
  width: 100%;
  padding-top: 20px;
}

.action-buttons {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.action-btn {
  flex: 1;
  height: 40px;
  font-size: 14px;
  background-color: #f0f0f0;
  color: #666;
  border: none;
  border-radius: 8px;
}

.copyright {
  text-align: center;
  font-size: 12px;
  color: #999;
  margin-top: 10px;
}
</style>